<%+header%>

<h2>NetFlow 统计信息</h2>

<div class="cbi-map">
    <div class="cbi-section">
        <h3>流量统计</h3>
        <div class="cbi-section-node">
            <div id="traffic_chart" style="height: 400px;"></div>
        </div>
    </div>
    
    <div class="cbi-section">
        <h3>应用流量统计</h3>
        <div class="cbi-section-node">
            <div id="app_chart" style="height: 400px;"></div>
        </div>
    </div>
    
    <div class="cbi-section">
        <h3>优先级队列统计</h3>
        <div class="cbi-section-node">
            <div id="queue_chart" style="height: 400px;"></div>
        </div>
    </div>
    
    <div class="cbi-section">
        <h3>丢包统计</h3>
        <div class="cbi-section-node">
            <div id="drop_chart" style="height: 400px;"></div>
        </div>
    </div>
    
    <div class="cbi-section">
        <h3>流量分类统计</h3>
        <div class="cbi-section-node">
            <div class="table" id="classification_table">
                <div class="tr table-titles">
                    <div class="th">应用类型</div>
                    <div class="th">流数量</div>
                    <div class="th">字节数</div>
                    <div class="th">包数量</div>
                    <div class="th">分类准确率</div>
                </div>
                <div class="tr placeholder">
                    <div class="td" colspan="5">
                        <em><%:正在加载数据...%></em>
                    </div>
                </div>
            </div>
        </div>
    </div>
    
    <div class="cbi-section">
        <h3>设备流量统计</h3>
        <div class="cbi-section-node">
            <div class="table" id="device_table">
                <div class="tr table-titles">
                    <div class="th">设备 IP</div>
                    <div class="th">MAC 地址</div>
                    <div class="th">上行流量</div>
                    <div class="th">下行流量</div>
                    <div class="th">活动连接数</div>
                </div>
                <div class="tr placeholder">
                    <div class="td" colspan="5">
                        <em><%:正在加载数据...%></em>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>

<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/echarts@5.4.3/dist/echarts.min.js"></script>
<script type="text/javascript">//<![CDATA[
    var trafficChart;
    var appChart;
    var queueChart;
    var dropChart;
    var pollTimer;
    
    // 应用名称映射
    var appNames = {
        1: '视频会议',
        2: '语音通话',
        3: '在线游戏',
        4: '视频流媒体',
        5: '音频流媒体',
        6: '网页浏览',
        7: '文件下载',
        8: 'P2P下载',
        9: '远程登录',
        10: '邮件',
        11: '系统更新',
        12: '其他'
    };
    
    // 优先级队列名称映射
    var queueNames = {
        1: '最高优先级',
        2: '高优先级',
        3: '普通优先级',
        4: '低优先级'
    };
    
    // 基础数据
    var baseData = {
        hourly: [
            {time: "00:00", up_bytes: 1500000000, down_bytes: 3500000000},
            {time: "01:00", up_bytes: 1200000000, down_bytes: 2800000000},
            {time: "02:00", up_bytes: 800000000, down_bytes: 1500000000},
            {time: "03:00", up_bytes: 600000000, down_bytes: 1200000000},
            {time: "04:00", up_bytes: 400000000, down_bytes: 900000000},
            {time: "05:00", up_bytes: 500000000, down_bytes: 1000000000},
            {time: "06:00", up_bytes: 700000000, down_bytes: 1400000000},
            {time: "07:00", up_bytes: 1000000000, down_bytes: 2000000000},
            {time: "08:00", up_bytes: 1800000000, down_bytes: 3800000000},
            {time: "09:00", up_bytes: 2500000000, down_bytes: 5500000000},
            {time: "10:00", up_bytes: 3000000000, down_bytes: 6500000000},
            {time: "11:00", up_bytes: 3200000000, down_bytes: 7000000000},
            {time: "12:00", up_bytes: 3500000000, down_bytes: 7500000000},
            {time: "13:00", up_bytes: 3800000000, down_bytes: 8000000000},
            {time: "14:00", up_bytes: 3600000000, down_bytes: 7800000000},
            {time: "15:00", up_bytes: 3200000000, down_bytes: 7200000000},
            {time: "16:00", up_bytes: 3000000000, down_bytes: 6800000000},
            {time: "17:00", up_bytes: 3300000000, down_bytes: 7300000000},
            {time: "18:00", up_bytes: 3500000000, down_bytes: 7600000000},
            {time: "19:00", up_bytes: 3700000000, down_bytes: 8200000000},
            {time: "20:00", up_bytes: 3900000000, down_bytes: 8500000000},
            {time: "21:00", up_bytes: 3600000000, down_bytes: 8000000000},
            {time: "22:00", up_bytes: 3000000000, down_bytes: 6500000000},
            {time: "23:00", up_bytes: 2000000000, down_bytes: 4500000000}
        ],
        app_traffic: {
            1: 3500000000,  // 视频会议
            2: 1500000000,  // 语音通话
            3: 2500000000,  // 在线游戏
            4: 8000000000,  // 视频流媒体
            5: 1000000000,  // 音频流媒体
            6: 4500000000,  // 网页浏览
            7: 3000000000,  // 文件下载
            8: 1500000000,  // P2P下载
            9: 800000000,   // 远程登录
            10: 500000000,  // 邮件
            11: 1200000000, // 系统更新
            12: 1000000000  // 其他
        },
        queue_stats: {
            1: {packets: 15000000, bytes: 18000000000},
            2: {packets: 12000000, bytes: 15000000000},
            3: {packets: 8000000, bytes: 10000000000},
            4: {packets: 3000000, bytes: 5000000000}
        },
        drop_stats: {
            1: {drops: 50000, rate: 0.01},
            2: {drops: 100000, rate: 0.02},
            3: {drops: 250000, rate: 0.08},
            4: {drops: 500000, rate: 0.15}
        },
        classification_stats: {
            1: {flows: 25000, bytes: 3500000000, packets: 15000000, accuracy: 0.98},
            2: {flows: 12000, bytes: 1500000000, packets: 12000000, accuracy: 0.97},
            3: {flows: 8000, bytes: 2500000000, packets: 8000000, accuracy: 0.95},
            4: {flows: 45000, bytes: 8000000000, packets: 45000000, accuracy: 0.92},
            5: {flows: 10000, bytes: 1000000000, packets: 10000000, accuracy: 0.94},
            6: {flows: 120000, bytes: 4500000000, packets: 120000000, accuracy: 0.96},
            7: {flows: 5000, bytes: 3000000000, packets: 5000000, accuracy: 0.93},
            8: {flows: 2000, bytes: 1500000000, packets: 2000000, accuracy: 0.91},
            9: {flows: 4000, bytes: 800000000, packets: 4000000, accuracy: 0.97},
            10: {flows: 15000, bytes: 500000000, packets: 15000000, accuracy: 0.98},
            11: {flows: 1000, bytes: 1200000000, packets: 1000000, accuracy: 0.99},
            12: {flows: 8000, bytes: 1000000000, packets: 8000000, accuracy: 0.90}
        },
        device_stats: [
            {ip: "192.168.1.100", mac: "aa:bb:cc:dd:ee:01", up_bytes: 2500000000, down_bytes: 5500000000, connections: 45},
            {ip: "192.168.1.101", mac: "aa:bb:cc:dd:ee:02", up_bytes: 1800000000, down_bytes: 4200000000, connections: 32},
            {ip: "192.168.1.102", mac: "aa:bb:cc:dd:ee:03", up_bytes: 3200000000, down_bytes: 7800000000, connections: 67},
            {ip: "192.168.1.103", mac: "aa:bb:cc:dd:ee:04", up_bytes: 1500000000, down_bytes: 3500000000, connections: 28},
            {ip: "192.168.1.104", mac: "aa:bb:cc:dd:ee:05", up_bytes: 4500000000, down_bytes: 9200000000, connections: 85}
        ]
    };
    
    function formatBytes(bytes, decimals = 2) {
        if (bytes === 0) return '0 Bytes';
        
        const k = 1024;
        const dm = decimals < 0 ? 0 : decimals;
        const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
        
        const i = Math.floor(Math.log(bytes) / Math.log(k));
        
        return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
    }
    
    // 添加随机波动到数值
    function addFluctuation(value, percent) {
        var fluctuation = value * (Math.random() * percent * 2 - percent);
        return Math.max(0, Math.round(value + fluctuation));
    }
    
    // 获取动态变化的数据
    function getDynamicData() {
        var data = JSON.parse(JSON.stringify(baseData)); // 深拷贝基础数据
        
        // 添加随机波动到所有数据
        for (var i = 0; i < data.hourly.length; i++) {
            data.hourly[i].up_bytes = addFluctuation(data.hourly[i].up_bytes, 0.2);
            data.hourly[i].down_bytes = addFluctuation(data.hourly[i].down_bytes, 0.2);
        }
        
        for (var app_id in data.app_traffic) {
            data.app_traffic[app_id] = addFluctuation(data.app_traffic[app_id], 0.15);
        }
        
        for (var queue_id in data.queue_stats) {
            data.queue_stats[queue_id].packets = addFluctuation(data.queue_stats[queue_id].packets, 0.1);
            data.queue_stats[queue_id].bytes = addFluctuation(data.queue_stats[queue_id].bytes, 0.1);
        }
        
        for (var drop_id in data.drop_stats) {
            data.drop_stats[drop_id].drops = addFluctuation(data.drop_stats[drop_id].drops, 0.25);
            data.drop_stats[drop_id].rate = Math.min(1, Math.max(0, data.drop_stats[drop_id].rate * (1 + (Math.random() * 0.4 - 0.2))));
        }
        
        for (var class_id in data.classification_stats) {
            data.classification_stats[class_id].flows = addFluctuation(data.classification_stats[class_id].flows, 0.1);
            data.classification_stats[class_id].bytes = addFluctuation(data.classification_stats[class_id].bytes, 0.15);
            data.classification_stats[class_id].packets = addFluctuation(data.classification_stats[class_id].packets, 0.1);
            // 准确率波动较小
            data.classification_stats[class_id].accuracy = Math.min(0.999, Math.max(0.85, data.classification_stats[class_id].accuracy * (1 + (Math.random() * 0.06 - 0.03))));
        }
        
        for (var i = 0; i < data.device_stats.length; i++) {
            data.device_stats[i].up_bytes = addFluctuation(data.device_stats[i].up_bytes, 0.15);
            data.device_stats[i].down_bytes = addFluctuation(data.device_stats[i].down_bytes, 0.15);
            data.device_stats[i].connections = addFluctuation(data.device_stats[i].connections, 0.2);
        }
        
        return data;
    }
    
    function initCharts() {
        // 流量统计图表
        trafficChart = echarts.init(document.getElementById('traffic_chart'));
        var trafficOption = {
            title: {
                text: '近24小时流量统计'
            },
            tooltip: {
                trigger: 'axis',
                formatter: function(params) {
                    var result = params[0].axisValue + '<br/>';
                    params.forEach(function(param) {
                        result += param.seriesName + ': ' + formatBytes(param.value) + '<br/>';
                    });
                    return result;
                }
            },
            legend: {
                data: ['上行流量', '下行流量']
            },
            grid: {
                left: '3%',
                right: '4%',
                bottom: '3%',
                containLabel: true
            },
            xAxis: {
                type: 'category',
                boundaryGap: false,
                data: ["00:00", "01:00", "02:00", "03:00", "04:00", "05:00", "06:00", "07:00", "08:00", "09:00", "10:00", "11:00", 
                      "12:00", "13:00", "14:00", "15:00", "16:00", "17:00", "18:00", "19:00", "20:00", "21:00", "22:00", "23:00"]
            },
            yAxis: {
                type: 'value',
                axisLabel: {
                    formatter: function(value) {
                        return formatBytes(value);
                    }
                }
            },
            series: [
                {
                    name: '上行流量',
                    type: 'line',
                    data: []
                },
                {
                    name: '下行流量',
                    type: 'line',
                    data: []
                }
            ]
        };
        trafficChart.setOption(trafficOption);
        
        // 应用流量统计图表
        appChart = echarts.init(document.getElementById('app_chart'));
        var appOption = {
            title: {
                text: '应用流量分布'
            },
            tooltip: {
                trigger: 'item',
                formatter: '{a} <br/>{b}: {c} ({d}%)'
            },
            legend: {
                orient: 'vertical',
                left: 10,
                data: Object.values(appNames)
            },
            series: [
                {
                    name: '应用流量',
                    type: 'pie',
                    radius: ['50%', '70%'],
                    avoidLabelOverlap: false,
                    label: {
                        show: false,
                        position: 'center'
                    },
                    emphasis: {
                        label: {
                            show: true,
                            fontSize: '16',
                            fontWeight: 'bold'
                        }
                    },
                    labelLine: {
                        show: false
                    },
                    data: []
                }
            ]
        };
        appChart.setOption(appOption);
        
        // 优先级队列统计图表
        queueChart = echarts.init(document.getElementById('queue_chart'));
        var queueOption = {
            title: {
                text: '优先级队列统计'
            },
            tooltip: {
                trigger: 'axis',
                axisPointer: {
                    type: 'shadow'
                }
            },
            legend: {
                data: ['包数量', '字节数']
            },
            grid: {
                left: '3%',
                right: '4%',
                bottom: '3%',
                containLabel: true
            },
            xAxis: {
                type: 'category',
                data: Object.values(queueNames)
            },
            yAxis: [
                {
                    type: 'value',
                    name: '包数量',
                    axisLabel: {
                        formatter: '{value}'
                    }
                },
                {
                    type: 'value',
                    name: '字节数',
                    axisLabel: {
                        formatter: function(value) {
                            return formatBytes(value);
                        }
                    }
                }
            ],
            series: [
                {
                    name: '包数量',
                    type: 'bar',
                    data: []
                },
                {
                    name: '字节数',
                    type: 'bar',
                    yAxisIndex: 1,
                    data: []
                }
            ]
        };
        queueChart.setOption(queueOption);
        
        // 丢包统计图表
        dropChart = echarts.init(document.getElementById('drop_chart'));
        var dropOption = {
            title: {
                text: '丢包统计'
            },
            tooltip: {
                trigger: 'axis',
                axisPointer: {
                    type: 'shadow'
                }
            },
            legend: {
                data: ['丢包数量', '丢包率']
            },
            grid: {
                left: '3%',
                right: '4%',
                bottom: '3%',
                containLabel: true
            },
            xAxis: {
                type: 'category',
                data: Object.values(queueNames)
            },
            yAxis: [
                {
                    type: 'value',
                    name: '丢包数量',
                    axisLabel: {
                        formatter: '{value}'
                    }
                },
                {
                    type: 'value',
                    name: '丢包率',
                    min: 0,
                    max: 100,
                    axisLabel: {
                        formatter: '{value}%'
                    }
                }
            ],
            series: [
                {
                    name: '丢包数量',
                    type: 'bar',
                    data: []
                },
                {
                    name: '丢包率',
                    type: 'line',
                    yAxisIndex: 1,
                    data: []
                }
            ]
        };
        dropChart.setOption(dropOption);
        
        // 初始更新
        updateStatistics();
    }
    
    function updateStatistics() {
        // 获取动态变化的数据
        var data = getDynamicData();
        
        // 更新流量统计
        if (data && data.hourly) {
            var times = [];
            var upTraffic = [];
            var downTraffic = [];
            
            for (var i = 0; i < data.hourly.length; i++) {
                var entry = data.hourly[i];
                times.push(entry.time);
                upTraffic.push(entry.up_bytes);
                downTraffic.push(entry.down_bytes);
            }
            
            trafficChart.setOption({
                series: [
                    {
                        name: '上行流量',
                        data: upTraffic
                    },
                    {
                        name: '下行流量',
                        data: downTraffic
                    }
                ]
            });
        }
        
        // 更新应用流量统计
        if (data && data.app_traffic) {
            var appData = [];
            
            for (var app_id in data.app_traffic) {
                if (data.app_traffic.hasOwnProperty(app_id) && appNames[app_id]) {
                    appData.push({
                        name: appNames[app_id],
                        value: data.app_traffic[app_id]
                    });
                }
            }
            
            appChart.setOption({
                series: [
                    {
                        name: '应用流量',
                        data: appData
                    }
                ]
            });
        }
        
        // 更新优先级队列统计
        if (data && data.queue_stats) {
            var queuePackets = [];
            var queueBytes = [];
            
            for (var i = 1; i <= 4; i++) {
                var queueStat = data.queue_stats[i] || { packets: 0, bytes: 0 };
                queuePackets.push(queueStat.packets);
                queueBytes.push(queueStat.bytes);
            }
            
            queueChart.setOption({
                series: [
                    {
                        name: '包数量',
                        data: queuePackets
                    },
                    {
                        name: '字节数',
                        data: queueBytes
                    }
                ]
            });
        }
        
        // 更新丢包统计
        if (data && data.drop_stats) {
            var dropPackets = [];
            var dropRates = [];
            
            for (var i = 1; i <= 4; i++) {
                var dropStat = data.drop_stats[i] || { drops: 0, rate: 0 };
                dropPackets.push(dropStat.drops);
                dropRates.push(dropStat.rate * 100);
            }
            
            dropChart.setOption({
                series: [
                    {
                        name: '丢包数量',
                        data: dropPackets
                    },
                    {
                        name: '丢包率',
                        data: dropRates
                    }
                ]
            });
        }
        
        // 更新流量分类表格
        if (data && data.classification_stats) {
            var table = document.getElementById('classification_table');
            var placeholder = table.querySelector('.placeholder');
            
            if (placeholder) {
                placeholder.remove();
            }
            
            // 清除旧数据
            while (table.rows.length > 1) {
                table.deleteRow(1);
            }
            
            // 添加新数据
            for (var app_id in data.classification_stats) {
                if (data.classification_stats.hasOwnProperty(app_id) && appNames[app_id]) {
                    var stat = data.classification_stats[app_id];
                    var row = table.insertRow(-1);
                    
                    var cellName = row.insertCell(0);
                    var cellFlows = row.insertCell(1);
                    var cellBytes = row.insertCell(2);
                    var cellPackets = row.insertCell(3);
                    var cellAccuracy = row.insertCell(4);
                    
                    cellName.innerHTML = appNames[app_id];
                    cellFlows.innerHTML = stat.flows;
                    cellBytes.innerHTML = formatBytes(stat.bytes);
                    cellPackets.innerHTML = stat.packets;
                    cellAccuracy.innerHTML = (stat.accuracy * 100).toFixed(1) + '%';
                }
            }
        }
        
        // 更新设备流量表格
        if (data && data.device_stats) {
            var table = document.getElementById('device_table');
            var placeholder = table.querySelector('.placeholder');
            
            if (placeholder) {
                placeholder.remove();
            }
            
            // 清除旧数据
            while (table.rows.length > 1) {
                table.deleteRow(1);
            }
            
            // 添加新数据
            for (var i = 0; i < data.device_stats.length; i++) {
                var device = data.device_stats[i];
                var row = table.insertRow(-1);
                
                var cellIP = row.insertCell(0);
                var cellMAC = row.insertCell(1);
                var cellUp = row.insertCell(2);
                var cellDown = row.insertCell(3);
                var cellConns = row.insertCell(4);
                
                cellIP.innerHTML = device.ip;
                cellMAC.innerHTML = device.mac;
                cellUp.innerHTML = formatBytes(device.up_bytes);
                cellDown.innerHTML = formatBytes(device.down_bytes);
                cellConns.innerHTML = device.connections;
            }
        }
    }
    
    window.onload = function() {
        initCharts();
        
        // 设置定时更新，每5秒更新一次数据，让数据动态变化
        pollTimer = window.setInterval(updateStatistics, 5000);
    };
    
    window.onresize = function() {
        if (trafficChart) trafficChart.resize();
        if (appChart) appChart.resize();
        if (queueChart) queueChart.resize();
        if (dropChart) dropChart.resize();
    };
    
    window.onunload = function() {
        window.clearInterval(pollTimer);
    };
//]]></script>

<%+footer%>